package studiodiva.portfolio.client.view.workslides;

import static com.google.gwt.query.client.GQuery.$;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.IsWidget;
import com.google.gwt.user.client.ui.Widget;

import static studiodiva.portfolio.client.lib.lang.Lang.SECOND;
import static studiodiva.portfolio.client.lib.lang.Lang.doLater;
import static studiodiva.portfolio.client.lib.lang.Lang.no;

import studiodiva.portfolio.client.lib.even.EventFunction;
import studiodiva.portfolio.client.lib.view.View;
import studiodiva.portfolio.client.model.HasApplication;
import studiodiva.portfolio.client.model.titles.Title;
import studiodiva.portfolio.client.model.titles.Titles;
import studiodiva.portfolio.client.model.titles.Titles.TitleType;

public class WorksSlidesWidget extends View<IsWidget> implements ClickHandler {

  interface Binder extends UiBinder<Widget, WorksSlidesWidget> {}

  private static final int SLIDE_PERIOD = 10 * SECOND;
  private static final Binder uiBinder = GWT.create(Binder.class);

  @UiField
  Image currentImage;
  @UiField
  Image loadingImage;
  private final Timer changeTimer = new Timer() {
    @Override
    public void run() {
      onChangeTimeElapsed();
    }
  };
  private int currentIndex = 0;

  public WorksSlidesWidget() {
    initWidget(uiBinder.createAndBindUi(this));
    asWidget().addDomHandler(this, ClickEvent.getType());
  }

  @Override
  public void initialize(HasApplication app) {
    super.initialize(app);
    $(asWidget(), currentImage).hide();
    loadCurrentWork();
    if (no(getApplication().getTitles().getOpened())) doLater(1500, new Runnable() {
      public void run() {
        $(asWidget()).fadeIn(3000);
      }
    });
    changeTimer.scheduleRepeating(SLIDE_PERIOD);
    getApplication().getTitles().addHandler(Titles.ON_CHANGE, new EventFunction<Title>() {
      public void run(Title value) {
        updateTitleState(value);
      }
    });
  }

  public void onClick(ClickEvent event) {
    getWorks().showPage(currentIndex);
    getApplication().getTitles().open(TitleType.done);
  }

  private void close() {
    $(asWidget()).fadeOut(100);
  }

  private Title getWorks() {
    return getApplication().getTitles().getTitle(TitleType.done);
  }

  private void loadCurrentWork() {
    loadingImage.setResource(getWorks().getPage(currentIndex).getImage());
    loadingImage.setVisible(false);
    $(loadingImage).fadeIn(5 * SECOND);
    $(currentImage).fadeOut(2 * SECOND);
    switchImages();
  }

  private void onChangeTimeElapsed() {
    setNextIndex();
    loadCurrentWork();
  }

  private void open() {
    doLater(NORMAL_ANIMATION, new Runnable() {
      public void run() {
        $(asWidget()).fadeIn();
      }
    });
  }

  private void setNextIndex() {
    if (currentIndex == getWorks().getPageCount() - 1)
      currentIndex = 0;
    else currentIndex++;
  }

  private void switchImages() {
    Image tmpCurrentImage = currentImage;
    currentImage = loadingImage;
    loadingImage = tmpCurrentImage;
  }

  private void updateTitleState(Title title) {
    if (no(title))
      open();
    else close();
  }
}
